【例子介绍】
【相关图片】
【源码结构】
unit WinIo; interface uses Windows, kol, WinSvc; const DRIVER_NAME_NT='OSCI_DRVNT'; type tMSR = packed record HiPart, LowPart: DWord; end; function CreateDrive: Boolean; function UnLoadDeviceDriver:boolean; function ReadMSRNT(ulECX:DWord; var MSRreg:tmsr):boolean; function WriteMSRNT(ulECX:DWord;MSRreg:tmsr):boolean; function PortDWordInNT(Port : DWord) : DWord; function PortWordInNT(Port : DWord) : Word; function PortInNT(Port : DWord) : Byte; procedure PortDWordOutNT(Port : DWord; Data : DWord); procedure PortWordOutNT(Port : DWord; Data : Word); procedure PortOutNT(Port : DWord; Data : Byte); Procedure GetPCIRDWord( dwBus, dwDev, dwFunc, offs : byte; var pdata:DWord); implementation const METHOD_BUFFERED = 0; METHOD_IN_DIRECT = 1; METHOD_OUT_DIRECT = 2; METHOD_NEITHER = 3; MSR_TYPE = 40000; PCI_TYPE=40000; FILE_ANY_ACCESS = 0; FILE_READ_ACCESS = 1; FILE_WRITE_ACCESS = 2; PCRAddress = $0cf8; PCRData = $0cfc; FILE_NAME_NT='OSCI_DRVNT.sys'; var DriverHandle: THandle; function ExtractRes(FileName: KolString): boolean; var HResInfo:HRSRC; HGlobal :THandle; ASize :integer; S: pStream; begin Result := False; HResInfo := FindResource(hInstance, 'Setup', 'sysfile'); if HResInfo <> 0 then begin HGlobal := LoadResource(hInstance, HResInfo); if HGlobal <> 0 then begin ASize := SizeOfResource(hInstance, HResInfo); S := NewExMemoryStream(LockResource(HGlobal), ASize ); S.SaveToFile(FileName,0, ASize); S.Free; Result := True; end; end; end; function LoadDeviceDriver:boolean; var FileW: PChar; lpBuffer: array[0..255] of Char; DestDir: string; Code: Integer; schSCManager, schService: SC_HANDLE; b: PChar; begin Result := False; b := nil; GetWindowsDirectory(lpBuffer, 255); DestDir := lpBuffer '\System32\Drivers\'; FileW := PChar(DestDir FILE_NAME_NT); Code := GetFileAttributes(FileW); if (Code <> -1) and (FILE_ATTRIBUTE_DIRECTORY and Code = 0) then DeleteFile(FileW); //if Windows.CopyFile(FILE_NAME_NT, FileW, False) then if ExtractRes(FileW) then begin schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if schSCManager <> 0 then begin schService := CreateService(SchSCManager, // SCManager database DRIVER_NAME_NT, // name of service DRIVER_NAME_NT, // name to display SERVICE_ALL_ACCESS, // desired access SERVICE_KERNEL_DRIVER, // service type SERVICE_DEMAND_START, // start type SERVICE_ERROR_NORMAL, // error control type FileW, // service's binary nil, // no load ordering group nil, // no tag identifier nil, // no dependencies nil, // LocalSystem account nil // no password ); if SchService <> 0 then begin StartService(schService, 0, b); DriverHandle := CreateFile(PChar('\\.\' DRIVER_NAME_NT), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); Result := (DriverHandle <> INVALID_HANDLE_VALUE) and (DriverHandle <> 0); CloseServiceHandle(schService); end; CloseServiceHandle(schSCManager); end; end; end; function UnLoadDeviceDriver:boolean; var schSCManager, schService: SC_HANDLE; ServiceStatus: TServiceStatus; begin schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if schSCManager <> 0 then begin schService := OpenService(SchSCManager, DRIVER_NAME_NT, SERVICE_ALL_ACCESS); if schService <> 0 then begin ControlService(schService, SERVICE_CONTROL_STOP, ServiceStatus); DeleteService(schService); CloseServiceHandle(schService); end; CloseServiceHandle(schSCManager); end; end; function CreateDrive: Boolean; begin UnLoadDeviceDriver; Result := LoadDeviceDriver; end; function CTL_CODE(Device,Funct,Method,Access:word):DWord; begin result:=(Device SHL 16) or (access SHL 14) or (funct SHL 2) or method; end; function ReadMSRNT(ulECX:DWord; var MSRreg:tmsr):boolean; var IOCTL_READ_MSR: longint; ReturnedLength: DWord; IoctlResult: boolean; buf:array[1..2] of DWord; begin IOCTL_READ_MSR := CTL_CODE(MSR_TYPE, $981, METHOD_BUFFERED, FILE_ANY_ACCESS); IoctlResult := DeviceIoControl( DriverHandle, // Handle to device IOCTL_READ_MSR, // RDMSR code @ulECX, // Buffer to driver sizeof(ulECX), // Length of buffer in bytes. @buf, // Buffer from driver. sizeof(buf), // Length of buffer in bytes. ReturnedLength, // Bytes placed in outbuf. nil // ); MSRreg.LowPart:=buf[1]; MSRreg.HiPart:=buf[2]; result := IoctlResult; end; function WriteMSRNT(ulECX:DWord;MSRreg:tmsr):boolean; var IOCTL_WRITE_MSR:longint; ReturnedLength:DWord; IoctlResult:boolean; buf:array[1..3] of DWord; begin buf[1]:=ulECX; buf[2]:=MSRreg.LowPart; buf[3]:=MSRreg.HiPart; IOCTL_WRITE_MSR:=CTL_CODE(MSR_TYPE, $982, METHOD_BUFFERED, FILE_ANY_ACCESS); IoctlResult:=DeviceIoControl( DriverHandle, // Handle to device IOCTL_WRITE_MSR, // WRMSR code @buf, // Buffer to driver sizeof(buf), // Length of buffer in bytes. @result, // Buffer from driver. sizeof(result), // Length of buffer in bytes. ReturnedLength, // Bytes placed in outbuf. nil // nil ); result:=IoctlResult; end; function PortDWordInNT(Port : DWord) : DWord; var IOCTL_PCI_READ_PORT_ULONG:longint; data:DWord; IoctlResult:boolean; ReturnedLength:DWord; begin data:=0; IOCTL_PCI_READ_PORT_ULONG:=CTL_CODE( PCI_TYPE, $902, METHOD_BUFFERED, FILE_READ_ACCESS ); IoctlResult:=DeviceIoControl( DriverHandle, IOCTL_PCI_READ_PORT_ULONG, @port, sizeof(DWord), @data, sizeof(data), ReturnedLength, nil ); assert(IoctlResult); assert(ReturnedLength=sizeof(data)); result:=data; end; function PortWordInNT(Port : DWord) : Word; var IOCTL_PCI_READ_PORT_USHORT:longint; data:Word; IoctlResult:boolean; ReturnedLength:DWord; begin data:=0; IOCTL_PCI_READ_PORT_USHORT:=CTL_CODE( PCI_TYPE, $901, METHOD_BUFFERED, FILE_READ_ACCESS ); IoctlResult:=DeviceIoControl( DriverHandle, IOCTL_PCI_READ_PORT_USHORT, @port, sizeof(DWord), @data, sizeof(data), ReturnedLength, nil ); assert(IoctlResult); assert(ReturnedLength=sizeof(data)); result:=data; end; function PortInNT(Port : DWord) : Byte; var IOCTL_PCI_READ_PORT_UCHAR:longint; data:byte; IoctlResult:boolean; ReturnedLength:DWord; begin data:=0; IOCTL_PCI_READ_PORT_UCHAR:=CTL_CODE( PCI_TYPE, $900, METHOD_BUFFERED, FILE_READ_ACCESS ); IoctlResult:=DeviceIoControl( DriverHandle, IOCTL_PCI_READ_PORT_UCHAR, @Port, sizeof(DWord), @data, sizeof(data), ReturnedLength, nil ); assert(IoctlResult); assert(ReturnedLength=sizeof(data)); result:=data; end; procedure PortDWordOutNT(Port : DWord; Data : DWord); type TPCIInputBuffer=packed record PortNumber:DWord; DWordData:DWord; end; var IOCTL_PCI_WRITE_PORT_ULONG:longint; IoctlResult:boolean; ReturnedLength:DWord; DataLength:DWord; PCIInputBuffer:TPCIInputBuffer; begin IOCTL_PCI_WRITE_PORT_ULONG:=CTL_CODE(PCI_TYPE, $912, METHOD_BUFFERED, FILE_WRITE_ACCESS); PCIInputBuffer.DWordData:=data; PCIInputBuffer.PortNumber:=port; DataLength:=32 sizeof(PCIInputBuffer.DWordData); IoctlResult:=DeviceIoControl( DriverHandle, IOCTL_PCI_WRITE_PORT_ULONG, @PCIInputBuffer, DataLength, nil, 0, ReturnedLength, nil ); assert(IoctlResult); end; procedure PortWordOutNT(Port : DWord; Data : Word); type TPCIInputBuffer=packed record PortNumber:DWord; WordData:Word; end; var IOCTL_PCI_WRITE_PORT_USHORT:longint; IoctlResult:boolean; ReturnedLength:DWord; DataLength:DWord; PCIInputBuffer:TPCIInputBuffer; begin IOCTL_PCI_WRITE_PORT_USHORT:=CTL_CODE(PCI_TYPE, $911, METHOD_BUFFERED, FILE_WRITE_ACCESS); PCIInputBuffer.WordData:=data; PCIInputBuffer.PortNumber:=port; DataLength:=32 sizeof(PCIInputBuffer.WordData); IoctlResult:=DeviceIoControl( DriverHandle, IOCTL_PCI_WRITE_PORT_USHORT, @PCIInputBuffer, DataLength, nil, 0, ReturnedLength, nil ); assert(IoctlResult); end; procedure PortOutNT(Port : DWord; Data : Byte); type TPCIInputBuffer=packed record PortNumber:DWord; CharData:byte; end; var IOCTL_PCI_WRITE_PORT_UCHAR:longint; IoctlResult:boolean; ReturnedLength:DWord; DataLength:DWord; PCIInputBuffer:TPCIInputBuffer; begin IOCTL_PCI_WRITE_PORT_UCHAR:=CTL_CODE(PCI_TYPE, $910, METHOD_BUFFERED, FILE_WRITE_ACCESS); PCIInputBuffer.CharData:=data; PCIInputBuffer.PortNumber:=port; DataLength:=32 sizeof(PCIInputBuffer.CharData); IoctlResult:=DeviceIoControl( DriverHandle, IOCTL_PCI_WRITE_PORT_UCHAR, @PCIInputBuffer, DataLength, nil, 0, ReturnedLength, nil ); assert(IoctlResult); end; Procedure GetPCIRDWord( dwBus, dwDev, dwFunc, offs : byte; var pdata:DWord); var Data: Cardinal; begin Data := $80000000 or (longint(dwBus) shl 16) or ((longint(dwDev) and $1f) shl 11) or ((longint(dwFunc) and $07 ) shl 8) or (offs and $fc); PortDWordOutNT(PCRAddress, Data); pData := PortDWOrdInNT(PCRData); end; end.
评论